package perplexity;

import DataSetPackage.DataSet;
import DataSetPackage.DataSetStorage;
import DataSetPackage.ProductView;
import DataSetPackage.SimpleView;
import DataSetPackage.View;
import EstimatorPackage.EmpSuffix;
import EstimatorPackage.EstimatorExp;
import EstimatorPackage.IndependentProductEst;
import EstimatorPackage.LaPlaceSuffix;
import EstimatorPackage.SimSuffixEstimatorExp;
import HierarchyPackage.AffixHierarchies.SuffixHierarchy;
import HierarchyPackage.AffixHierarchies.WordHierarchy;
import HierarchyPackage.Hierarchy;
import HierarchyPackage.ProductHierarchy.ProductHierarchy;
import OrderedCoverPackage.NSuffixOCEstimator;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.osdtsystem.utils.MemoryStorage;
import org.osdtsystem.utils.Storage;

/**
 *
 * @author Martin Haulrich
 */
public class OCsufestimator implements EstimatorPer {

    public NSuffixOCEstimator est;

    final int N;

    public OCsufestimator(String fn, String ocestfn, int N, EstimatorExp prior) throws IOException {

        this.N = N;
//        Storage storage = new MemoryStorage();
//
//        DataSet ds = new DataSetStorage(storage);
//
//
//        BufferedReader input = new BufferedReader(new FileReader(fn));
//        // Just a counter to control how much data is readb
//        int rl = 0;
//
//        // List of words. Used to create empirical estimator
//        List<String> wl = new ArrayList<String>();
//
//        int maxread = Integer.MAX_VALUE;//Integer.parseInt(args[1]);
//
//        int lc = 0;
//        String line;
//        System.err.println("Reading data...");
//
////        List<List<String>> ngrams = new ArrayList<List<String>>();
//        while (((line = input.readLine()) != null) && rl < maxread) {
//            rl++;
//            for (int i = 0; i < N - 1; i++) {
//                line = "<s> " + line;
//            }
//            line = line + " </s>";
//            String[] tokens = line.split(" ");
////                System.err.println(line);
////                for (int i = 0; i < tokens.length - 1; i++) {
////                    List<String> ng = new ArrayList<String>(2);
////                    ng.add("^" + tokens[i]);
////                    ng.add("^" + tokens[i + 1]);
////                    ngrams.add(ng);
////                    ds.add(ng);
////                }
//
//            for (int i = 0; i < tokens.length - (N - 1); i++) {
//                List<String> ng = new ArrayList<String>(N);
//                for (int j = 0; j < N; j++) {
//                    ng.add("^" + tokens[i + j]);
//                }
//
//                ds.add(ng);
////                    System.err.println(ng);
//            }
////                for (String t : tokens) {
//            for (int i = (N - 2); i < tokens.length; i++) {
//
//                String t = tokens[i];
//                // Add prefix to word
//                String w = "^" + t;
//                wl.add(w);
//            }
//
//            lc++;
//        }
//        input.close();

//
//        System.err.println("Lines read: " + lc);
//        System.err.println("words read: " + wl.size());
//        System.err.println("");
//
//        System.err.println("Creating prior...");
//        EmpSuffix es = new EmpSuffix(wl);
//
//        EmpSuffix ls = new LaPlaceSuffix(es);
//        // Create estimator to handle expression
//        EstimatorExp ees = new SimSuffixEstimatorExp(es);
//        EstimatorExp els = new SimSuffixEstimatorExp(ls);
//
//
//
//        // Array of estimators used in product-estimator
//        //EstimatorExp[] ee = {se, se};
////            EstimatorExp[] ee = {els, ees};
//        EstimatorExp[] ee = new EstimatorExp[N];
//        for (int i = 0; i < (N - 1); i++) {
//            ee[i] = els;
//        }
//        ee[N - 1] = ees;
//
//        // Create product-estimator
//        IndependentProductEst ie = new IndependentProductEst(ee);
//
//        EstimatorExp pe = ie;

//        System.err.println("Creating product dataset");
//        // Make empty dataset
//
//        System.err.println("DatasetSize: " + ds.size());

        // Create suffix-hiearchy
        SuffixHierarchy sufhier = new SuffixHierarchy();

//
//
//
//        View[] views = new View[N];
//        for (int i = 0; i < N; i++) {
//            views[i] = new SimpleView(i, ds);
//        }
//        ProductView pv = new ProductView(ds, views);
//
////            Hierarchy[] hiers = {sufhier, sufhier};

        Hierarchy[] hiers = new Hierarchy[N];
        for (int i = 0; i < N; i++) {
            hiers[i] = sufhier;
            
        }

        // And now we make the suf x suf producthierarchy
        ProductHierarchy phier = new ProductHierarchy(hiers);


//        System.err.println("Lines read: " + lc);
//        System.err.println("words read: " + wl.size());
//        System.err.println("");
//
//        System.err.println("Creating prior...");
//        EmpSuffix es = new EmpSuffix(wl);
//
//        EmpSuffix ls = new LaPlaceSuffix(es);
//        // Create estimator to handle expression
//        EstimatorExp ees = new SimSuffixEstimatorExp(es, 100);
//        EstimatorExp els = new SimSuffixEstimatorExp(ls, 100);
//
//
//
//        // Array of estimators used in product-estimator
//        //EstimatorExp[] ee = {se, se};
////            EstimatorExp[] ee = {els, ees};
//        EstimatorExp[] ee = {els, els, ees};
//
//        // Create product-estimator
//        IndependentProductEst ie = new IndependentProductEst(ee);
//
//        EstimatorExp pe = ie;
//
//        System.err.println("Creating product dataset");
//        // Make empty dataset
//
//        System.err.println("DatasetSize: " + ds.size());
//
//        // Create suffix-hiearchy
//        SuffixHierarchy sufhier = new SuffixHierarchy();
//
//        // Data for hierarchy is at index 0.
//
//        SimpleView sufdv1 = new SimpleView(0, ds);
//        SimpleView sufdv2 = new SimpleView(1, ds);
//        SimpleView sufdv3 = new SimpleView(2, ds);
//
//        // Create productView
////            View[] views = {sufdv1, sufdv2};
//        View[] views = {sufdv1, sufdv2, sufdv3};
//        ProductView pv = new ProductView(ds, views);
//
////            Hierarchy[] hiers = {sufhier, sufhier};
//        Hierarchy[] hiers = {sufhier, sufhier, sufhier};
//
//        // And now we make the suf x suf producthierarchy
//        ProductHierarchy phier = new ProductHierarchy(hiers);
//
//
//        //
//        // Just a counter to control how much data is readb
//        int rl = 0;
//
//        // List of words. Used to create empirical estimator
//        List<String> wl = new ArrayList<String>();
//
//        int maxread = Integer.MAX_VALUE;//Integer.parseInt(args[1]);
//
//        int lc = 0;
//        String line;
//        System.err.println("Reading data...");
//
//        List<List<String>> ngrams = new ArrayList<List<String>>();
//        while (((line = input.readLine()) != null) && rl < maxread) {
//            rl++;
//            line = "<s> " + line + " </s>";
//            String[] tokens = line.split(" ");
//
//            for (int i = 0; i < tokens.length - 1; i++) {
//                List<String> ng = new ArrayList<String>(2);
//                ng.add("^" + tokens[i]);
//                ng.add("^" + tokens[i + 1]);
//                ngrams.add(ng);
//
//            }
//
//            for (String t : tokens) {
//                // Add prefix to word
//                String w = "^" + t;
//                wl.add(w);
//            }
//
//            lc++;
//        }
//        input.close();
//
//        System.err.println("Lines read: " + lc);
//        System.err.println("words read: " + wl.size());
//        System.err.println("");
//
//        System.err.println("Creating prior...");
//
//        EmpSuffix es = new EmpSuffix(wl);
//        EstimatorExp ees = new SimSuffixEstimatorExp(es, 100);
// EmpSuffix ls = new LaPlaceSuffix(es);
//  EstimatorExp els = new SimSuffixEstimatorExp(ls, 100);
//
//        // Array of estimators used in product-estimator
//
//        //EstimatorExp[] ee = {ees, ees};
//        EstimatorExp[] ee = {els, ees};
//
//        // Create product-estimator
//        IndependentProductEst pe = new IndependentProductEst(ee);
//
//        // Create suffix-hiearchy
//        SuffixHierarchy sufhier = new SuffixHierarchy();
//
//        Hierarchy[] hiers = {sufhier, sufhier};
//
//        // And now we make the suf x suf producthierarchy
//        ProductHierarchy phier = new ProductHierarchy(hiers);

        est = new NSuffixOCEstimator(ocestfn, phier, prior);
    }

    public double getEstimate(List<String> tokens) throws Exception {
        //  System.err.println("hher");
        List<String> nt = new ArrayList<String>(tokens.size());
        for (String s : tokens) {
            nt.add("^" + s);
        }
        while (nt.size() < N) {
            nt.add(0, "^<s>");
        }
        //     System.err.println("");
        return est.getEstimate(nt);
    }

    public double getEstimate2(List<String> tokens) throws Exception {
        //  System.err.println("hher");
        
        return est.getEstimate2(tokens);

    }
}
